/*
 * Written by edhong Jan. 2008
 *  sample arithmetic DECODER using QccPack,
 * based  mostly from QccENTArithmeticEncode documentation  
 *
 * This file is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 * 
 * This file is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 * 
 * 
 */

#include "libQccPack.h" 
#define FIRST_CONTEXT 0 
#define SECOND_CONTEXT 1 
#define BLOCK_LENGTH 1
#define SYMBOL_STREAM_LENGTH 12

int main(int argc, char *argv[]) 
{ 
  int symbol_stream[SYMBOL_STREAM_LENGTH]; 
  QccBitBuffer input_buffer; 
  QccENTArithmeticModel *model = NULL; 

  /*  int num_contexts = 2; */
  int num_symbols[2] = {2, 10};  
  char filename[] = "arithtest.bits";

  QccInit(argc, argv); 
  QccBitBufferInitialize(&input_buffer); 
  QccConvertToQccString(input_buffer.filename, filename);

  input_buffer.type = QCCBITBUFFER_INPUT; 
  if (QccBitBufferStart(&input_buffer)) 
    { 
      QccErrorAddMessage("%s: Error calling QccBitBufferStart()", 
			 argv[0]); 
      QccErrorExit(); 
    } 

  printf("Decoding file %s\n", filename);

  if ((model = QccENTArithmeticDecodeStart(&input_buffer, 
					   num_symbols, 
					   2, 
					   NULL, 
					   QCCENT_ANYNUMBITS)) == NULL) 
    { 
      QccErrorAddMessage("%s: Error calling QccENTArithmeticDecodeStart()", 
			 argv[0]); 
      QccErrorExit(); 
    } 

  int counter;
  int errorvalue; 
  for (counter = 0; counter < SYMBOL_STREAM_LENGTH; counter++) {

    if (counter %2 == 0) 
      errorvalue = QccENTArithmeticSetModelContext(model, FIRST_CONTEXT);
    else 
      errorvalue = QccENTArithmeticSetModelContext(model, SECOND_CONTEXT);

    if (errorvalue) { 
      QccErrorAddMessage("%s: Error calling QccENTArithmeticSetModelContext()", 
			 argv[0]); 
      QccErrorExit(); 
    }
 
    if (QccENTArithmeticDecode(&input_buffer, 
			       model, 
			       &symbol_stream[counter], 
			       BLOCK_LENGTH)) 
      { 
	QccErrorAddMessage("%s: Error calling QccENTArithmeticDecode()", 
			   argv[0]); 
	QccErrorExit(); 
      } 

    printf("%d\n", symbol_stream[counter]);

  }

  if (QccENTArithmeticSetModelContext(model, SECOND_CONTEXT))
    { 
      QccErrorAddMessage("%s: Error calling QccENTArithmeticSetModelContext()", 
			 argv[0]); 
      QccErrorExit(); 
    } 

  if (QccBitBufferEnd(&input_buffer)) 
    { 
      QccErrorAddMessage("%s: Error calling QccBitBufferEnd()", 
			 argv[0]); 
      QccErrorExit(); 
    } 

  QccENTArithmeticFreeModel(model); 


  QccExit; 
} 
